package com.zc.im.seqsvr.filter;

import cn.hutool.json.JSONUtil;
import com.sun.istack.internal.NotNull;
import com.zc.im.common.constant.enums.ResultEnum;
import com.zc.im.common.vo.Result;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.server.WebFilter;
import org.springframework.web.server.WebFilterChain;
import reactor.core.publisher.Mono;

import java.net.InetSocketAddress;

/**
 * Project：im
 * Date：2022/4/13
 * Time：18:54
 * Description：上下文过滤器 记录所接受的请求
 *
 * @author Challen.Zhang
 * @version 1.0
 */
@Slf4j
@Order(value = Ordered.HIGHEST_PRECEDENCE)
@Configuration
@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.REACTIVE)
public class ReactiveRequestContextFilter implements WebFilter {

    @Override
    public Mono<Void> filter(ServerWebExchange serverWebExchange, WebFilterChain webFilterChain) {
        ServerHttpRequest request = serverWebExchange.getRequest();
        InetSocketAddress remoteAddress = request.getRemoteAddress();
        if (remoteAddress == null) {
            log.error("获取到的 remoteAddress 为空! exchange:[{}]", serverWebExchange);
            return writeResponse(serverWebExchange.getResponse(), new Result<>(ResultEnum.BAD_REQUEST));
        }
        log.info("请求来源 : [{}] 请求方式 : [{}] 请求地址 : [{}]", request.getRemoteAddress(), request.getMethod(), request.getURI());
        return webFilterChain.filter(serverWebExchange);
    }

    @NotNull
    private Mono<Void> writeResponse(ServerHttpResponse response, Result<?> result) {
        return response.writeWith(
                Mono.just(response.bufferFactory().wrap(JSONUtil.toJsonStr(result).getBytes())));
    }
}
